﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.ExtensibleStorage;
using Autodesk.Revit.UI;
using YArchitech.Controls;
using YArchitech.Revit;
using YArchitech.Revit.RevitExtension;
using YJKArchUtils.Utils;
using YJKRevitRampModule.Forms;

namespace YJKRevitRampModule.RampDataManager
{
	public class BarrierFreeRampManager
	{
		public BarrierFreeRampManager(ExternalCommandData cmdData)
		{
			this.m_Revit = cmdData;
			this.m_RampAtLevel = this.m_Revit.Application.ActiveUIDocument.Document.ActiveView.GenLevel;
		}

		public bool Create()
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			this.CreateLineType(document, BarrierFreeRampManager.m_strCorssLineStyle, new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0));
			BarrierFreeRampForm barrierFreeRampForm = new BarrierFreeRampForm(this.m_Revit, false);
			while (barrierFreeRampForm.ShowDialog() == DialogResult.OK)
			{
				if (barrierFreeRampForm.DlgCloseType == BarrierFreeRampForm.ResultType.RT_GetAngle)
				{
					double drawAngle = 0.0;
					if (this.GetAngle(ref drawAngle))
					{
						barrierFreeRampForm.DrawAngle = drawAngle;
						barrierFreeRampForm.SaveDlgData();
					}
				}
				else if (barrierFreeRampForm.DlgCloseType == BarrierFreeRampForm.ResultType.RT_DrawRamp)
				{
					XYZ xyz = this.PickPointByBase("请确定坡道插入点", null);
					if (xyz != null)
					{
						this.CreateBarrierFreeRamp(document, xyz, barrierFreeRampForm);
					}
				}
			}
			this.EraseLineType(document, BarrierFreeRampManager.m_strCorssLineStyle);
			return true;
		}

		public bool Edit()
		{
			UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
			Group group = this.SelectRampGroup(activeUIDocument);
			if (group == null)
			{
				return false;
			}
			List<string> list = BarrierFreeRampManager.ReadXData(group);
			if (list.Count < 1)
			{
				YJKMessageBox.Show("不能提取坡道参数。");
				return false;
			}
			Document document = activeUIDocument.Document;
			this.CreateLineType(document, BarrierFreeRampManager.m_strCorssLineStyle, new Autodesk.Revit.DB.Color(byte.MaxValue, 0, 0));
			BarrierFreeRampForm barrierFreeRampForm = new BarrierFreeRampForm(this.m_Revit, true);
			barrierFreeRampForm.DlgDataFromStringList(list);
			while (barrierFreeRampForm.ShowDialog() == DialogResult.OK)
			{
				if (barrierFreeRampForm.DlgCloseType == BarrierFreeRampForm.ResultType.RT_GetAngle)
				{
					double drawAngle = 0.0;
					if (this.GetAngle(ref drawAngle))
					{
						barrierFreeRampForm.DrawAngle = drawAngle;
						barrierFreeRampForm.SaveDlgData();
					}
				}
				else if (barrierFreeRampForm.DlgCloseType == BarrierFreeRampForm.ResultType.RT_DrawRamp)
				{
					Transaction transaction = new Transaction(document, "EraseEnt");
					transaction.Start();
					try
					{
						document.Delete(group.Id);
						transaction.Commit();
					}
					catch
					{
						YJKMessageBox.Show("删除原坡道失败！");
						transaction.Commit();
						return false;
					}
					int count = list.Count;
					double num = Convert.ToDouble(list[count - 2]);
					double num2 = Convert.ToDouble(list[count - 1]);
					this.CreateBarrierFreeRamp(document, new XYZ(num, num2, 0.0), barrierFreeRampForm);
					break;
				}
			}
			this.EraseLineType(document, BarrierFreeRampManager.m_strCorssLineStyle);
			return true;
		}

		private void CreateBarrierFreeRamp(Autodesk.Revit.DB.Document doc, XYZ ptPos, BarrierFreeRampForm dlg)
		{
			string strFloorTypeName;
			if (dlg.m_strRampStructStyle == "整体")
			{
				this.m_dFloorThick = AssistFunc.mmToFeet(10.0);
				strFloorTypeName = "坡道 - 10mm - " + dlg.MaterialId.IntegerValue.ToString();
			}
			else
			{
				this.m_dFloorThick = AssistFunc.mmToFeet(dlg.FloorThick);
				strFloorTypeName = string.Format("坡道 - {0}mm - {1}", dlg.FloorThick, dlg.MaterialId.IntegerValue);
			}
			this.m_FloorType = this.CreateFloorType(doc, this.m_dFloorThick, strFloorTypeName, dlg.MaterialId);
			if (this.m_FloorType == null)
			{
				return;
			}
			string strWallTypeName = "坡道 - 10mm - " + dlg.MaterialId.IntegerValue.ToString();
			this.m_WallType = this.CreateWallType(doc, AssistFunc.mmToFeet(10.0), strWallTypeName, dlg.MaterialId);
			if (this.m_WallType == null)
			{
				return;
			}
			this.m_RailingSymbolLeft = dlg.LeftRailSymbol;
			this.m_RailingSymbolRight = dlg.RightRailSymbol;
			this.m_RailingSymbolEnd = dlg.EndRailSymbol;
			this.m_dRailOffset = AssistFunc.mmToFeet(50.0);
			this.m_dBottomElev = this.m_RampAtLevel.Elevation + dlg.GetBottomElev();
			bool bDrawRailingLeft = dlg.m_bDrawRailingLeft;
			bool bDrawRailingRight = dlg.m_bDrawRailingRight;
			double num = (double)dlg.RampSlope;
			double num2 = this.m_dBottomElev;
			double rampWidth = dlg.RampWidth;
			double platWidth = dlg.PlatWidth;
			XYZ realInsertPoint = dlg.GetRealInsertPoint();
			XYZ xyz = new XYZ(ptPos.X, ptPos.Y, realInsertPoint.Z) - realInsertPoint;
			XYZ xyz2 = new XYZ(xyz.X, xyz.Y, num2);
			ElementSet eleSet = new ElementSet();
			Transaction transaction = new Transaction(doc, "CreateRamp");
			transaction.Start();
			try
			{
				for (int i = 0; i < dlg.m_lstBaseLine.Count; i++)
				{
					num2 += dlg.m_lstRampLen[i] / num;
					XYZ xyz3 = dlg.m_lstBaseLine[i].Direction.Normalize();
					XYZ xyz4 = xyz2 + xyz3 * dlg.m_lstRampLen[i];
					XYZ xyz5 = new XYZ(xyz4.X, xyz4.Y, num2);
					if (dlg.m_strRampStructStyle == "整体")
					{
						this.CreateRamp(xyz2, xyz5, rampWidth, bDrawRailingLeft, bDrawRailingRight, true, ref eleSet);
					}
					else
					{
						this.CreateRamp(xyz2, xyz5, rampWidth, bDrawRailingLeft, bDrawRailingRight, false, ref eleSet);
					}
					if (i == 0)
					{
						this.CreateRailEnd(xyz2, xyz5, rampWidth, bDrawRailingLeft, bDrawRailingRight, ref eleSet);
					}
					if (i == dlg.m_lstBaseLine.Count - 1)
					{
						this.CreateRailEnd(xyz5, xyz2, rampWidth, bDrawRailingRight, bDrawRailingLeft, ref eleSet);
					}
					xyz2 = xyz5;
					if (i < dlg.m_lstBaseLine.Count - 1)
					{
						XYZ xyz6 = dlg.m_lstBaseLine[i + 1].Direction.Normalize();
						if (dlg.m_strRampStructStyle == "整体")
						{
							this.CreatePlat(xyz2, xyz3, xyz6, platWidth, rampWidth, bDrawRailingLeft, bDrawRailingRight, true, ref eleSet);
						}
						else
						{
							this.CreatePlat(xyz2, xyz3, xyz6, platWidth, rampWidth, bDrawRailingLeft, bDrawRailingRight, false, ref eleSet);
						}
						double num3 = platWidth - 0.5 * rampWidth;
						xyz2 = xyz2 + xyz3 * num3 + xyz6 * num3;
					}
				}
				if (dlg.m_bMarkDirection)
				{
					XYZ ptPos2 = new XYZ(xyz.X, xyz.Y, this.m_dBottomElev);
					XYZ direction = dlg.m_lstBaseLine[0].Direction;
					this.CreateDirectionMark(doc, ptPos2, direction, ref eleSet);
				}
				transaction.Commit();
			}
			catch (Exception ex)
			{
				YJKMessageBox.Show(ex.Message);
				transaction.RollBack();
				return;
			}
			Transaction transaction2 = new Transaction(doc, "MakeGroup");
			transaction2.Start();
			try
			{
				Group group = RevitVersionFuncs.NewGroup(doc, eleSet);
				int num4 = this.CalculateGroupNumber(doc);
				group.GroupType.Name = "无障碍坡道" + num4.ToString();
				transaction2.Commit();
				List<string> list = dlg.DlgDataToStringList();
				list.Add(ptPos.X.ToString());
				list.Add(ptPos.Y.ToString());
				BarrierFreeRampManager.WriteXData(group, list);
			}
			catch (Exception ex2)
			{
				YJKMessageBox.Show(ex2.Message);
				transaction2.RollBack();
			}
		}

		private void CreateRamp(XYZ ptStart, XYZ ptEnd, double dRampWid, bool bRailingL, bool bRailingR, bool bWhole, ref ElementSet Elements)
		{
			XYZ xyz = new XYZ(ptEnd.X, ptEnd.Y, ptStart.Z);
			if (ptStart.DistanceTo(xyz) < 0.01)
			{
				return;
			}
			XYZ xyz2 = (xyz - ptStart).Normalize();
			XYZ xyz3 = Geometry.RotateTo(xyz2, Math.PI*.5, XYZ.BasisZ);
			double num = dRampWid / 2.0;
			XYZ xyz4 = ptStart + xyz3 * num;
			XYZ xyz5 = ptStart - xyz3 * num;
			XYZ xyz6 = xyz - xyz3 * num;
			XYZ xyz7 = xyz + xyz3 * num;
			CurveArray curveArray = new CurveArray();
			curveArray.Append(YJKLineEx.YJKGetBound(xyz4, xyz5));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz5, xyz6));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz6, xyz7));
			curveArray.Append(YJKLineEx.YJKGetBound(xyz7, xyz4));
			UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
			Floor floor = activeUIDocument.Document.Create.NewFloor(curveArray, this.m_FloorType, this.m_RampAtLevel, false, XYZ.BasisZ);
			Common.UpdateModel(activeUIDocument, false);
			SlabShapeEditor slabShapeEditor = floor.SlabShapeEditor;
			if (slabShapeEditor != null)
			{
				slabShapeEditor.DrawPoint(ptEnd - xyz3 * num);
				slabShapeEditor.DrawPoint(ptEnd + xyz3 * num);
			}
			Elements.Insert(floor);
			double dLength = ptStart.DistanceTo(xyz);
			double dEndHeight = ptEnd.Z - ptStart.Z;
			double dAngle = XYZ.BasisX.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
			if (bRailingL)
			{
				this.CreateRailing(this.m_RailingSymbolLeft, xyz4 - xyz3 * this.m_dRailOffset, dLength, dEndHeight, dAngle, ref Elements);
			}
			if (bRailingR)
			{
				this.CreateRailing(this.m_RailingSymbolRight, xyz5 + xyz3 * this.m_dRailOffset, dLength, dEndHeight, dAngle, ref Elements);
			}
			if (bWhole)
			{
				double num2 = this.m_dFloorThick / (ptStart.DistanceTo(xyz) / ptStart.DistanceTo(ptEnd));
				double num3 = this.m_WallType.Width / 2.0;
				XYZ xyz8 = ptStart + xyz3 * (num - num3);
				XYZ xyz9 = ptEnd + xyz3 * (num - num3);
				xyz8 = new XYZ(xyz8.X, xyz8.Y, xyz8.Z - num2);
				xyz9 = new XYZ(xyz9.X, xyz9.Y, xyz9.Z - num2);
				Wall wall = this.CreateTiltWall(xyz8, xyz9, this.m_WallType, this.m_RampAtLevel);
				if (wall != null)
				{
					Elements.Insert(wall);
				}
				xyz8 = ptStart - xyz3 * (num - num3);
				xyz9 = ptEnd - xyz3 * (num - num3);
				xyz8 = new XYZ(xyz8.X, xyz8.Y, xyz8.Z - num2);
				xyz9 = new XYZ(xyz9.X, xyz9.Y, xyz9.Z - num2);
				Wall wall2 = this.CreateTiltWall(xyz8, xyz9, this.m_WallType, this.m_RampAtLevel);
				if (wall2 != null)
				{
					Elements.Insert(wall2);
				}
			}
		}

		private void CreateRailEnd(XYZ ptStart, XYZ ptEnd, double dRampWid, bool bRailingL, bool bRailingR, ref ElementSet Elements)
		{
			XYZ xyz = new XYZ(ptStart.X, ptStart.Y, ptStart.Z + AssistFunc.mmToFeet(900.0));
			XYZ xyz2 = (new XYZ(ptEnd.X, ptEnd.Y, xyz.Z) - xyz).Normalize();
			XYZ xyz3 = Geometry.RotateTo(xyz2, Math.PI*.5, XYZ.BasisZ);
			double num = dRampWid / 2.0 - this.m_dRailOffset;
			double dAngle = XYZ.BasisX.AngleOnPlaneTo(xyz2, XYZ.BasisZ);
			xyz += xyz2 * AssistFunc.mmToFeet(20.0);
			if (bRailingL && this.m_RailingSymbolLeft != null)
			{
				this.CreateRailingEnd(this.m_RailingSymbolEnd, xyz + xyz3 * num, dAngle, ref Elements);
			}
			if (bRailingR && this.m_RailingSymbolRight != null)
			{
				this.CreateRailingEnd(this.m_RailingSymbolEnd, xyz - xyz3 * num, dAngle, ref Elements);
			}
		}

		private void CreatePlat(XYZ ptStart, XYZ vt1, XYZ vt2, double dPlatWid, double dRampWid, bool bRailingL, bool bRailingR, bool bWhole, ref ElementSet Elements)
		{
			XYZ xyz;
			XYZ xyz2;
			XYZ xyz3;
			XYZ xyz4;
			XYZ xyz5;
			XYZ xyz6;
			if (vt1.AngleOnPlaneTo(vt2, XYZ.BasisZ) < Math.PI)
			{
				xyz = ptStart + vt2 * dRampWid / 2.0;
				xyz2 = xyz + vt1 * (dPlatWid - dRampWid);
				xyz3 = xyz2 + vt2 * (dPlatWid - dRampWid);
				xyz4 = xyz3 + vt1 * dRampWid;
				xyz5 = xyz4 - vt2 * dPlatWid;
				xyz6 = xyz5 - vt1 * dPlatWid;
			}
			else
			{
				xyz = ptStart - vt2 * dRampWid / 2.0;
				xyz2 = xyz + vt1 * dPlatWid;
				xyz3 = xyz2 + vt2 * dPlatWid;
				xyz4 = xyz3 - vt1 * dRampWid;
				xyz5 = xyz4 - vt2 * (dPlatWid - dRampWid);
				xyz6 = xyz5 - vt1 * (dPlatWid - dRampWid);
			}
			CurveArray curveArray = new CurveArray();
			if (xyz.DistanceTo(xyz2) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz, xyz2));
			}
			if (xyz2.DistanceTo(xyz3) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz2, xyz3));
			}
			if (xyz3.DistanceTo(xyz4) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz3, xyz4));
			}
			if (xyz4.DistanceTo(xyz5) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz4, xyz5));
			}
			if (xyz5.DistanceTo(xyz6) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz5, xyz6));
			}
			if (xyz6.DistanceTo(xyz) > BarrierFreeRampManager.m_dMinWallLen)
			{
				curveArray.Append(YJKLineEx.YJKGetBound(xyz6, xyz));
			}
			Floor floor = this.m_Revit.Application.ActiveUIDocument.Document.Create.NewFloor(curveArray, this.m_FloorType, this.m_RampAtLevel, false, XYZ.BasisZ);
			Elements.Insert(floor);
			XYZ xyz7 = (xyz6 - xyz).Normalize();
			XYZ xyz8 = xyz + xyz7 * this.m_dRailOffset;
			XYZ xyz9 = xyz6 - xyz7 * this.m_dRailOffset;
			xyz7 = (xyz4 - xyz3).Normalize();
			XYZ xyz10 = xyz3 + xyz7 * this.m_dRailOffset;
			XYZ xyz11 = xyz4 - xyz7 * this.m_dRailOffset;
			XYZ xyz12 = this.ExtenTwoLineIntersect(xyz8, xyz8 + vt1 * 100.0, xyz10, xyz10 - vt2 * 100.0);
			XYZ xyz13 = this.ExtenTwoLineIntersect(xyz9, xyz9 + vt1 * 100.0, xyz11, xyz11 - vt2 * 100.0);
			if (bRailingL)
			{
				double dLength = xyz8.DistanceTo(xyz12);
				double dAngle = XYZ.BasisX.AngleOnPlaneTo(vt1, XYZ.BasisZ);
				this.CreateRailing(this.m_RailingSymbolLeft, xyz8, dLength, 0.0, dAngle, ref Elements);
				dLength = xyz12.DistanceTo(xyz10);
				dAngle = XYZ.BasisX.AngleOnPlaneTo(vt2, XYZ.BasisZ);
				this.CreateRailing(this.m_RailingSymbolLeft, xyz12, dLength, 0.0, dAngle, ref Elements);
			}
			if (bRailingR)
			{
				double dLength2 = xyz9.DistanceTo(xyz13);
				double dAngle2 = XYZ.BasisX.AngleOnPlaneTo(vt1, XYZ.BasisZ);
				this.CreateRailing(this.m_RailingSymbolLeft, xyz9, dLength2, 0.0, dAngle2, ref Elements);
				dLength2 = xyz13.DistanceTo(xyz11);
				dAngle2 = XYZ.BasisX.AngleOnPlaneTo(vt2, XYZ.BasisZ);
				this.CreateRailing(this.m_RailingSymbolLeft, xyz13, dLength2, 0.0, dAngle2, ref Elements);
			}
			if (bWhole)
			{
				double num = this.m_WallType.Width / 2.0;
				xyz7 = (xyz6 - xyz).Normalize();
				XYZ xyz14 = xyz + xyz7 * num;
				XYZ xyz15 = xyz6 - xyz7 * num;
				xyz7 = (xyz4 - xyz3).Normalize();
				XYZ xyz16 = xyz3 + xyz7 * num;
				XYZ xyz17 = xyz4 - xyz7 * num;
				XYZ xyz18 = this.ExtenTwoLineIntersect(xyz14, xyz14 + vt1 * 100.0, xyz16, xyz16 - vt2 * 100.0);
				XYZ xyz19 = this.ExtenTwoLineIntersect(xyz15, xyz15 + vt1 * 100.0, xyz17, xyz17 - vt2 * 100.0);
				Wall wall = this.CreateTiltWall(xyz14, xyz18, this.m_WallType, this.m_RampAtLevel);
				if (wall != null)
				{
					Elements.Insert(wall);
				}
				Wall wall2 = this.CreateTiltWall(xyz18, xyz16, this.m_WallType, this.m_RampAtLevel);
				if (wall2 != null)
				{
					Elements.Insert(wall2);
				}
				Wall wall3 = this.CreateTiltWall(xyz15, xyz19, this.m_WallType, this.m_RampAtLevel);
				if (wall3 != null)
				{
					Elements.Insert(wall3);
				}
				Wall wall4 = this.CreateTiltWall(xyz19, xyz17, this.m_WallType, this.m_RampAtLevel);
				if (wall4 != null)
				{
					Elements.Insert(wall4);
				}
			}
		}

		private void CreateDirectionMark(Autodesk.Revit.DB.Document doc, XYZ ptPos, XYZ vtDir, ref ElementSet Elements)
		{
			string text = "向上";
			double num = AssistFunc.mmToFeet(3.5);
			double num2 = num * (double)doc.ActiveView.Scale;
			double num3 = 3.0 * num2;
			double lineWidth = (double)this.GetLength(text) * num;
			XYZ xyz = vtDir.Normalize();
			XYZ xyz2 = Geometry.RotateTo(xyz, Math.PI*.5, XYZ.BasisZ);
			CurveArray curveArray = new CurveArray();
			XYZ xyz3 = ptPos + xyz * num3;
			curveArray.Append(YJKLineEx.YJKGetBound(ptPos, xyz3));
			XYZ xyz4 = xyz3 - xyz * (num3 / 3.0);
			XYZ startPoint = xyz4 + xyz2 * (num3 / 9.0);
			XYZ startPoint2 = xyz4 - xyz2 * (num3 / 9.0);
			curveArray.Append(YJKLineEx.YJKGetBound(startPoint, xyz3));
			curveArray.Append(YJKLineEx.YJKGetBound(startPoint2, xyz3));
			foreach (object obj in doc.Create.NewDetailCurveArray(doc.ActiveView, curveArray))
			{
				DetailCurve detailCurve = (DetailCurve)obj;
				Elements.Insert(detailCurve);
			}
			XYZ origin = ptPos - xyz * num2;
            TextAlignFlags textAlign = (TextAlignFlags)1152;
			TextNote textNode = doc.GetTextNode(doc.ActiveView, origin, xyz, xyz2, lineWidth, textAlign, text);
			if (textNode != null)
			{
				(doc.GetElement(textNode.GetTypeId()) as TextNoteType).get_Parameter(BuiltInParameter.TEXT_SIZE).Set(num);
				Elements.Insert(textNode);
			}
		}

		private int GetLength(string str)
		{
			if (str.Length == 0)
			{
				return 0;
			}
			Encoding encoding = new ASCIIEncoding();
			int num = 0;
			byte[] bytes = encoding.GetBytes(str);
			for (int i = 0; i < bytes.Length; i++)
			{
				if (bytes[i] == 63)
				{
					num += 2;
				}
				else
				{
					num++;
				}
			}
			return num;
		}

		private bool GetAngle(ref double angle)
		{
			XYZ xyz = this.PickPointByBase("请确定角度起点", null);
			if (xyz == null)
			{
				return false;
			}
			XYZ xyz2 = this.PickPointByBase("请确定角度终点", xyz);
			if (xyz2 == null)
			{
				return false;
			}
			angle = XYZ.BasisX.AngleOnPlaneTo(xyz2 - xyz, XYZ.BasisZ);
			angle = Geometry.formatAngle(angle);
			return true;
		}

		private XYZ PickPointByBase(string sCommandTip, XYZ ptBase)
		{
			List<ElementId> lstCurveId = new List<ElementId>();
			if (ptBase != null)
			{
				lstCurveId = this.DrawCrossFlag(ptBase);
			}
			try
			{
				XYZ xyz = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint(sCommandTip);
				this.DeleteCrossFlag(lstCurveId);
				return new XYZ(xyz.X, xyz.Y, 0.0);
			}
			catch
			{
				this.DeleteCrossFlag(lstCurveId);
			}
			return null;
		}

		private List<ElementId> DrawCrossFlag(XYZ ptPos)
		{
			UIDocument activeUIDocument = this.m_Revit.Application.ActiveUIDocument;
			List<ElementId> list = new List<ElementId>();
			Transaction transaction = new Transaction(activeUIDocument.Document);
			transaction.Start("DrawCrossFlag");
			try
			{
				double num = AssistFunc.mmToFeet(200.0);
				CurveArray curveArray = new CurveArray();
				XYZ startPoint = new XYZ(ptPos.X - num, ptPos.Y + num, 0.0);
				XYZ endPoint = new XYZ(ptPos.X + num, ptPos.Y - num, 0.0);
				curveArray.Append(YJKLineEx.YJKGetBound(startPoint, endPoint));
				startPoint = new XYZ(ptPos.X + num, ptPos.Y + num, 0.0);
				endPoint = new XYZ(ptPos.X - num, ptPos.Y - num, 0.0);
				curveArray.Append(YJKLineEx.YJKGetBound(startPoint, endPoint));
				Autodesk.Revit.DB.View activeView = activeUIDocument.ActiveView;
				foreach (object obj in activeUIDocument.Document.Create.NewDetailCurveArray(activeView, curveArray))
				{
					DetailCurve detailCurve = (DetailCurve)obj;
					if (this.m_LineStyle != null)
					{
						detailCurve.LineStyle = this.m_LineStyle;
					}
					list.Add(detailCurve.Id);
				}
				transaction.Commit();
			}
			catch
			{
				transaction.RollBack();
			}
			return list;
		}

		private void DeleteCrossFlag(List<ElementId> lstCurveId)
		{
			Transaction transaction = null;
			transaction = new Transaction(this.m_Revit.Application.ActiveUIDocument.Document);
			transaction.Start("delete temp elements");
			foreach (ElementId elementId in lstCurveId)
			{
				try
				{
					this.m_Revit.Application.ActiveUIDocument.Document.Delete(elementId);
				}
				catch
				{
				}
			}
			transaction.Commit();
		}

		private void CreateRailing(FamilySymbol RailSymbol, XYZ ptPos, double dLength, double dEndHeight, double dAngle, ref ElementSet Elements)
		{
			if (RailSymbol == null)
			{
				return;
			}
			if (dLength < AssistFunc.mmToFeet(100.0))
			{
				return;
			}
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			UnifiedModified.ActivateFamilySymbol(RailSymbol);
			FamilyInstance familyInstance = document.Create.NewFamilyInstance(ptPos, RailSymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
			if (familyInstance == null)
			{
				return;
			}
			document.Regenerate();
			Parameter parameter = familyInstance.GetParameter("水平长度");
			if (parameter != null && !parameter.IsReadOnly)
			{
				parameter.Set(dLength);
			}
			Parameter parameter2 = familyInstance.GetParameter("末端高度");
			if (parameter2 != null && !parameter2.IsReadOnly)
			{
				parameter2.Set(dEndHeight);
			}
			Line line = YJKLineEx.YJKGetUnBound(ptPos, XYZ.BasisZ);
			ElementTransformUtils.RotateElement(document, familyInstance.Id, line, dAngle - Math.PI*.5);
			Elements.Insert(familyInstance);
		}

		private void CreateRailingEnd(FamilySymbol RailSymbol, XYZ ptPos, double dAngle, ref ElementSet Elements)
		{
			if (RailSymbol == null)
			{
				return;
			}
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			UnifiedModified.ActivateFamilySymbol(RailSymbol);
			FamilyInstance familyInstance = document.Create.NewFamilyInstance(ptPos, RailSymbol, (Autodesk.Revit.DB.Structure.StructuralType)0);
			if (familyInstance == null)
			{
				return;
			}
			Line line = YJKLineEx.YJKGetUnBound(ptPos, XYZ.BasisZ);
			ElementTransformUtils.RotateElement(document, familyInstance.Id, line, dAngle + Math.PI*.5);
			Elements.Insert(familyInstance);
		}

		private XYZ ExtenTwoLineIntersect(XYZ ptS1, XYZ ptE1, XYZ ptS2, XYZ ptE2)
		{
			Curve curve = YJKLineEx.YJKGetUnBound(ptS1, ptE1 - ptS1);
			Line line = YJKLineEx.YJKGetUnBound(ptS2, ptE2 - ptS2);
			IntersectionResultArray intersectionResultArray = new IntersectionResultArray();
            if ((int)curve.Intersect(line, out intersectionResultArray) != 8)
			{
				return null;
			}
			if (intersectionResultArray == null || intersectionResultArray.IsEmpty)
			{
				return null;
			}
			return intersectionResultArray.get_Item(0).XYZPoint;
		}

		private Wall CreateTiltWall(XYZ ptTopStart, XYZ ptTopEnd, WallType wallType, Level wallAtLevel)
		{
			if (ptTopStart.Z < this.m_dBottomElev)
			{
				ptTopStart = new XYZ(ptTopStart.X, ptTopStart.Y, this.m_dBottomElev);
			}
			if (ptTopEnd.Z < this.m_dBottomElev)
			{
				ptTopEnd = new XYZ(ptTopEnd.X, ptTopEnd.Y, this.m_dBottomElev);
			}
			XYZ xyz = new XYZ(ptTopStart.X, ptTopStart.Y, this.m_dBottomElev);
			XYZ xyz2 = new XYZ(ptTopEnd.X, ptTopEnd.Y, this.m_dBottomElev);
			IList<Curve> list = new List<Curve>();
			if (xyz.DistanceTo(ptTopStart) > BarrierFreeRampManager.m_dMinWallLen)
			{
				list.Add(YJKLineEx.YJKGetBound(xyz, ptTopStart));
			}
			if (ptTopStart.DistanceTo(ptTopEnd) > BarrierFreeRampManager.m_dMinWallLen)
			{
				list.Add(YJKLineEx.YJKGetBound(ptTopStart, ptTopEnd));
			}
			if (ptTopEnd.DistanceTo(xyz2) > BarrierFreeRampManager.m_dMinWallLen)
			{
				list.Add(YJKLineEx.YJKGetBound(ptTopEnd, xyz2));
			}
			if (xyz2.DistanceTo(xyz) > BarrierFreeRampManager.m_dMinWallLen)
			{
				list.Add(YJKLineEx.YJKGetBound(xyz2, xyz));
			}
			if (list.Count < 3)
			{
				return null;
			}
			Wall wall = Wall.Create(this.m_Revit.Application.ActiveUIDocument.Document, list, wallType.Id, wallAtLevel.Id, true);
			wall.GetParameter(BuiltInParameter.WALL_BASE_OFFSET).Set(this.m_dBottomElev - wallAtLevel.Elevation);
			wall.GetParameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(ElementId.InvalidElementId);
			return wall;
		}

		private WallType CreateWallType(Autodesk.Revit.DB.Document doc, double dWallThick, string strWallTypeName, ElementId materialId)
		{
			WallType wallType = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(WallType)).ToElements())
			{
				WallType wallType2 = element as WallType;
				if (wallType2 != null && wallType2.Kind == null)
				{
					if (wallType2.Name == strWallTypeName)
					{
						return wallType2;
					}
					if (wallType == null && wallType2.get_Parameter(BuiltInParameter.FUNCTION_PARAM).AsInteger() == 1)
					{
						wallType = wallType2;
					}
				}
			}
			if (wallType == null)
			{
				YJKMessageBox.Show("创建坡道时，没有合适的墙作模板");
				return null;
			}
			WallType wallType3 = null;
			Transaction transaction = new Transaction(doc, "NewType");
			transaction.Start();
			try
			{
				wallType3 = (wallType.Duplicate(strWallTypeName) as WallType);
				CompoundStructure compoundStructure = wallType3.GetCompoundStructure();
				IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
				layers[0].Width = dWallThick;
				layers[0].MaterialId = materialId;
				for (int i = 1; i < layers.Count; i++)
				{
					CompoundStructureLayer compoundStructureLayer = layers[i];
					if ((int)compoundStructureLayer.Function == 1)
					{
						compoundStructureLayer.Width = dWallThick;
						compoundStructureLayer.MaterialId = materialId;
					}
					else
					{
						layers.RemoveAt(i);
						i--;
					}
				}
				compoundStructure.SetLayers(layers);
				compoundStructure.StructuralMaterialIndex = 0;
				wallType3.SetCompoundStructure(compoundStructure);
				transaction.Commit();
			}
			catch
			{
				YJKMessageBox.Show("创建墙类型失败!");
				transaction.RollBack();
				return null;
			}
			return wallType3;
		}

		private FloorType CreateFloorType(Autodesk.Revit.DB.Document doc, double dFloorThick, string strFloorTypeName, ElementId materialId)
		{
			FloorType floorType = null;
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(FloorType)).ToElements())
			{
				FloorType floorType2 = element as FloorType;
				if (floorType2 != null)
				{
					if (floorType2.Name.CompareTo(strFloorTypeName) == 0)
					{
						return floorType2;
					}
					if (floorType == null && floorType2.Name.CompareTo("基础底板 1") != 0)
					{
						floorType = floorType2;
					}
				}
			}
			if (floorType == null)
			{
				YJKMessageBox.Show("创建坡道时，找不到合适的模板");
				return null;
			}
			FloorType floorType3 = null;
			Transaction transaction = new Transaction(doc, "NewType");
			transaction.Start();
			try
			{
				floorType3 = (floorType.Duplicate(strFloorTypeName) as FloorType);
				CompoundStructure compoundStructure = floorType3.GetCompoundStructure();
				IList<CompoundStructureLayer> layers = compoundStructure.GetLayers();
				for (int i = 0; i < layers.Count; i++)
				{
					CompoundStructureLayer compoundStructureLayer = layers[i];
					if ((int)compoundStructureLayer.Function == 1)
					{
						compoundStructureLayer.Width = dFloorThick;
						compoundStructureLayer.MaterialId = materialId;
					}
					else
					{
						layers.RemoveAt(i);
						i--;
					}
				}
				compoundStructure.SetLayers(layers);
				compoundStructure.StructuralMaterialIndex = 0;
				floorType3.SetCompoundStructure(compoundStructure);
				transaction.Commit();
			}
			catch
			{
				YJKMessageBox.Show("创建楼板类型失败!");
				transaction.RollBack();
				return null;
			}
			return floorType3;
		}

        private void CreateLineType(Autodesk.Revit.DB.Document doc, string name, Autodesk.Revit.DB.Color color)
		{
			Transaction transaction = new Transaction(doc, "CreateLineType");
			transaction.Start();
			Category category = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			Category category2;
			if (category.SubCategories.Contains(name))
			{
				category2 = category.SubCategories.get_Item(name);
			}
			else
			{
				category2 = doc.Settings.Categories.NewSubcategory(category, name);
			}
			category2.LineColor = color;
            this.m_LineStyle = category2.GetGraphicsStyle((GraphicsStyleType)1);
			transaction.Commit();
		}

		private void EraseLineType(Autodesk.Revit.DB.Document doc, string name)
		{
			Transaction transaction = new Transaction(doc, "EraseLineType");
			transaction.Start();
			Category category = doc.Settings.Categories.get_Item(BuiltInCategory.OST_Lines);
			if (category.SubCategories.Contains(name))
			{
				Category category2 = category.SubCategories.get_Item(name);
				doc.Delete(category2.Id);
			}
			transaction.Commit();
		}

		public static bool IsBarrierFreeRamp(Element elem)
		{
			if (elem == null)
			{
				return false;
			}
			Schema schema = Schema.Lookup(new Guid(BarrierFreeRampManager.m_strXDataGuid));
			if (schema == null)
			{
				return false;
			}
			Entity entity = elem.GetEntity(schema);
			return entity.IsValid() && entity.Schema != null;
		}

		public static List<string> ReadXData(Element elem)
		{
			List<string> result = new List<string>();
			Transaction transaction = new Transaction(elem.Document, "ReadXData");
			transaction.Start();
			try
			{
				Schema schema = Schema.Lookup(new Guid(BarrierFreeRampManager.m_strXDataGuid));
				if (schema != null)
				{
					Entity entity = elem.GetEntity(schema);
					if (entity != null && entity.Schema != null)
					{
						Field field = schema.GetField("XDataField");
						result = entity.Get<IList<string>>(field).ToList<string>();
					}
				}
			}
			catch
			{
			}
			transaction.Commit();
			return result;
		}

		public static bool WriteXData(Element elem, List<string> lstItem)
		{
			Transaction transaction = new Transaction(elem.Document, "WriteXData");
			transaction.Start();
			try
			{
				Guid guid = new Guid(BarrierFreeRampManager.m_strXDataGuid);
				Schema schema = Schema.Lookup(guid);
				if (schema == null)
				{
					SchemaBuilder schemaBuilder = new SchemaBuilder(guid);
					schemaBuilder.SetSchemaName("HY_BarrierFreeRamp_XData");
					schemaBuilder.AddArrayField("XDataField", typeof(string));
					schema = schemaBuilder.Finish();
				}
				Entity entity = new Entity(schema);
				Field field = schema.GetField("XDataField");
				entity.Set<IList<string>>(field, lstItem);
				elem.SetEntity(entity);
				transaction.Commit();
				return true;
			}
			catch
			{
				transaction.RollBack();
			}
			return false;
		}

		private Group SelectRampGroup(UIDocument UIDoc)
		{
			Group result = null;
			try
			{
				GroupFilter groupFilter = new GroupFilter();
				Group group;
				do
				{
					Reference reference = UIDoc.Selection.PickObject((Autodesk.Revit.UI.Selection.ObjectType)1, groupFilter, "请选择要编辑的无障碍坡道");
					if (reference == null)
					{
						goto IL_44;
					}
					group = (UIDoc.Document.GetElement(reference) as Group);
				}
				while (!group.Name.Contains("无障碍坡道"));
				result = group;
				IL_44:;
			}
			catch
			{
			}
			return result;
		}

		private int CalculateGroupNumber(Autodesk.Revit.DB.Document doc)
		{
			string text = "无障碍坡道";
			int length = text.Length;
			List<int> list = new List<int>();
			foreach (Element element in new FilteredElementCollector(doc).OfClass(typeof(Group)).ToElements())
			{
				Group group = element as Group;
				if (group != null)
				{
					string name = group.GroupType.Name;
					int num = name.IndexOf(text);
					if (num != -1)
					{
						string value = name.Substring(num + length, name.Length - num - length);
						int item = 0;
						try
						{
							item = Convert.ToInt32(value);
						}
						catch (Exception)
						{
							continue;
						}
						list.Add(item);
					}
				}
			}
			if (list.Count == 0)
			{
				return 1;
			}
			list.Sort();
			return list[list.Count - 1] + 1;
		}

		private ExternalCommandData m_Revit;

		private Level m_RampAtLevel;

		private GraphicsStyle m_LineStyle;

		private FloorType m_FloorType;

		private WallType m_WallType;

		private FamilySymbol m_RailingSymbolLeft;

		private FamilySymbol m_RailingSymbolRight;

		private FamilySymbol m_RailingSymbolEnd;

		private double m_dRailOffset;

		private double m_dFloorThick;

		private double m_dBottomElev;

		private static double m_dMinWallLen = 0.005;

		private static string m_strCorssLineStyle = "红色交叉线";

		private static string m_strXDataGuid = "AC494717-24B1-4774-8A39-76E26320E149";
	}
}
